package com.cinema.controller;

import com.cinema.model.Movie;
import com.cinema.model.Schedule;
import com.cinema.model.Ticket;
import com.cinema.model.TicketType;
import com.cinema.model.User;
import com.cinema.service.MovieService;
import com.cinema.service.ScheduleService;
import com.cinema.service.TicketService;
import com.cinema.service.UserService;
import com.cinema.util.InputUtil;
import com.cinema.util.StringUtil;

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 用户控制器
 * 处理用户相关的操作
 */
public class UserController {
    private final UserService userService;
    private final MovieService movieService;
    private final ScheduleService scheduleService;
    private final TicketService ticketService;

    public UserController() {
        this.userService = new UserService();
        this.movieService = new MovieService();
        this.scheduleService = new ScheduleService();
        this.ticketService = new TicketService();
    }

    /**
     * 显示用户菜单
     */
    public void showMenu(User user) {
        boolean running = true;
        
        while (running) {
            displayUserMenu();
            int choice = InputUtil.readInt("请选择操作: ", 0, 6);
            
            switch (choice) {
                case 1:
                    changePassword(user);
                    break;
                case 2:
                    listShowingMovies();
                    break;
                case 3:
                    listSchedules();
                    break;
                case 4:
                    viewScheduleDetails();
                    break;
                case 5:
                    ticketOperations();
                    break;
                case 6:
                    System.out.println("正在退出登录...");
                    running = false;
                    break;
                case 0:
                    displayUserInfo(user);
                    break;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    /**
     * 显示用户菜单
     */
    private void displayUserMenu() {
        System.out.println("\n==================== 用户菜单 ====================");
        System.out.println("1. 修改密码");
        System.out.println("2. 查看正在上映影片");
        System.out.println("3. 查看场次信息");
        System.out.println("4. 查看指定场次详情");
        System.out.println("5. 票务操作");
        System.out.println("6. 退出登录");
        System.out.println("0. 查看个人信息");
        System.out.println("==================================================");
    }

    /**
     * 修改密码
     */
    private void changePassword(User user) {
        System.out.println("\n==================== 修改密码 ====================");
        
        String oldPassword = InputUtil.readNonEmptyString("请输入当前密码: ");
        String newPassword = InputUtil.readNonEmptyString("请输入新密码: ");
        String confirmPassword = InputUtil.readNonEmptyString("请确认新密码: ");
        
        if (!newPassword.equals(confirmPassword)) {
            System.out.println("两次输入的密码不一致！");
            InputUtil.pauseForUser();
            return;
        }

        if (userService.changePassword(user.getUsername(), oldPassword, newPassword)) {
            System.out.println("密码修改成功！");
        } else {
            System.out.println("密码修改失败，请检查当前密码是否正确！");
        }
        InputUtil.pauseForUser();
    }

    /**
     * 列出正在上映的影片
     */
    private void listShowingMovies() {
        System.out.println("\n==================== 正在上映影片 ====================");
        
        List<Movie> movies = movieService.getAllShowingMovies();
        if (movies.isEmpty()) {
            System.out.println("当前没有正在上映的影片！");
        } else {
            for (Movie movie : movies) {
                System.out.println("========================================");
                System.out.println("片名：" + movie.getTitle());
                System.out.println("导演：" + movie.getDirector());
                System.out.println("主演：" + movie.getActors());
                System.out.println("剧情简介：" + movie.getPlot());
                System.out.println("时长：" + movie.getDuration() + " 分钟");
                System.out.println("评分：" + movie.getRating() + " 分");
            }
        }
        InputUtil.pauseForUser();
    }

    /**
     * 列出场次信息
     */
    private void listSchedules() {
        System.out.println("\n==================== 场次信息 ====================");
        System.out.println("1. 当日场次");
        System.out.println("2. 近3日场次");
        System.out.println("3. 近一周场次");
        
                    int choice = InputUtil.readInt("请选择: ", 1, 3);
        List<Schedule> schedules = null;
        String period = "";
        
        switch (choice) {
            case 1:
                schedules = scheduleService.getTodaySchedules();
                period = "当日";
                break;
            case 2:
                schedules = scheduleService.getThreeDaysSchedules();
                period = "近3日";
                break;
            case 3:
                schedules = scheduleService.getWeekSchedules();
                period = "近一周";
                break;
        }

        if (schedules != null) {
            displaySchedules(schedules, period);
        }
        InputUtil.pauseForUser();
    }

    /**
     * 显示场次列表
     */
    private void displaySchedules(List<Schedule> schedules, String period) {
        if (schedules.isEmpty()) {
            System.out.println(period + "没有场次安排！");
        } else {
            System.out.println("\n" + StringUtil.repeat("=", 85));
            System.out.println("                            " + period + "场次列表");
            System.out.println(StringUtil.repeat("=", 85));
            
            System.out.println(String.format("%-10s %-24s %-8s %-16s %8s %12s", 
                "场次ID", "影片", "放映厅", "放映时间", "票价", "座位情况"));
            System.out.println(StringUtil.repeat("-", 85));
            
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd HH:mm");
            for (Schedule schedule : schedules) {
                Optional<Movie> movieOpt = movieService.findMovieById(schedule.getMovieId());
                String movieTitle = movieOpt.map(Movie::getTitle).orElse("未知影片");
                String formattedTitle = formatChineseString(movieTitle, 22);
                
                System.out.println(String.format("%-10s %-24s %-8s %-16s %8.2f %12s",
                    schedule.getScheduleId() != null && schedule.getScheduleId().length() >= 8 
                        ? schedule.getScheduleId().substring(0, 8) 
                        : (schedule.getScheduleId() != null ? schedule.getScheduleId() : "N/A"),
                    formattedTitle,
                    schedule.getHallId(),
                    schedule.getShowTime().format(formatter),
                    schedule.getPrice(),
                    schedule.getAvailableSeats() + "/" + schedule.getTotalSeats()));
            }
            System.out.println(StringUtil.repeat("=", 85));
        }
    }

    /**
     * 查看指定场次详情
     */
    private void viewScheduleDetails() {
        System.out.println("\n==================== 查看场次详情 ====================");
        
        String input = InputUtil.readString("请输入影片名称或场次ID: ");
        List<Schedule> schedules = new ArrayList<>();
        
        // 先尝试按影片名称查找
        Optional<Movie> movieOpt = movieService.findMovieByTitle(input);
        if (movieOpt.isPresent()) {
            schedules = scheduleService.getSchedulesByMovie(movieOpt.get().getMovieId());
        } else {
            // 再尝试按场次ID查找
            Optional<Schedule> scheduleOpt = scheduleService.findScheduleById(input);
            if (scheduleOpt.isPresent()) {
                schedules.add(scheduleOpt.get());
            }
        }

        if (schedules.isEmpty()) {
            System.out.println("没有找到相关场次！");
        } else {
            for (Schedule schedule : schedules) {
                displayScheduleDetail(schedule);
            }
        }
        InputUtil.pauseForUser();
    }

    /**
     * 显示场次详情
     */
    private void displayScheduleDetail(Schedule schedule) {
        Optional<Movie> movieOpt = movieService.findMovieById(schedule.getMovieId());
        String movieTitle = movieOpt.map(Movie::getTitle).orElse("未知影片");
        
        System.out.println("\n场次详情：");
        System.out.println("场次ID：" + schedule.getScheduleId());
        System.out.println("影片：" + movieTitle);
        System.out.println("放映厅：" + schedule.getHallId());
        System.out.println("放映时间：" + schedule.getShowTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        System.out.println("票价：" + schedule.getPrice() + " 元");
        System.out.println("总座位数：" + schedule.getTotalSeats());
        System.out.println("可用座位数：" + schedule.getAvailableSeats());
        
        // 显示座位图
        ticketService.displaySeatMap(schedule.getScheduleId());
    }

    /**
     * 票务操作
     */
    private void ticketOperations() {
        boolean running = true;
        
        while (running) {
            System.out.println("\n==================== 票务操作 ====================");
            System.out.println("1. 售票");
            System.out.println("2. 退票");
            System.out.println("3. 查询票务信息");
            System.out.println("4. 返回上级菜单");
            System.out.println("==================================================");
            
            int choice = InputUtil.readInt("请选择操作: ", 1, 4);
            
            switch (choice) {
                case 1:
                    sellTickets();
                    break;
                case 2:
                    refundTicket();
                    break;
                case 3:
                    queryTicket();
                    break;
                case 4:
                    running = false;
                    break;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    /**
     * 售票
     */
    private void sellTickets() {
        System.out.println("\n==================== 售票 ====================");
        
        // 首先显示今日可用场次
        List<Schedule> todaySchedules = scheduleService.getTodaySchedules();
        if (todaySchedules.isEmpty()) {
            System.out.println("今日没有可售票的场次！");
            InputUtil.pauseForUser();
            return;
        }
        
        System.out.println("今日可售票场次：");
        displaySchedules(todaySchedules, "今日");
        
        String scheduleId = InputUtil.readNonEmptyString("请输入场次ID: ");
        Optional<Schedule> scheduleOpt = scheduleService.findScheduleById(scheduleId);
        
        if (!scheduleOpt.isPresent()) {
            System.out.println("场次不存在！");
            InputUtil.pauseForUser();
            return;
        }

        Schedule schedule = scheduleOpt.get();
        
        // 显示场次信息和座位图
        displayScheduleDetail(schedule);
        
        if (schedule.getAvailableSeats() == 0) {
            System.out.println("该场次座位已售完！");
            InputUtil.pauseForUser();
            return;
        }

        // 选择座位
        int ticketCount = InputUtil.readInt("请输入购票数量: ", 1, schedule.getAvailableSeats());
        List<int[]> selectedSeats = new ArrayList<>();
        List<TicketType> ticketTypes = new ArrayList<>();
        
        for (int i = 0; i < ticketCount; i++) {
            System.out.println("\n选择第 " + (i + 1) + " 张票的座位：");
            
            int row = InputUtil.readInt("请输入座位行号: ", 1, schedule.getRows());
            int col = InputUtil.readInt("请输入座位列号: ", 1, schedule.getCols());
            
            // 转换为从0开始的索引
            row--;
            col--;
            
            if (!schedule.isSeatAvailable(row, col)) {
                System.out.println("该座位不可用，请重新选择！");
                i--; // 重新选择当前票的座位
                continue;
            }
            
            selectedSeats.add(new int[]{row, col});
            
            // 选择票类型
            System.out.println("请选择票类型：");
            System.out.println("1. 成人票 (原价)");
            System.out.println("2. 儿童票 (7折)");
            System.out.println("3. 学生票 (8折)");
            System.out.println("4. 老人票 (6折)");
            
            int typeChoice = InputUtil.readInt("请选择: ", 1, 4);
            TicketType ticketType;
            switch (typeChoice) {
                case 1:
                    ticketType = TicketType.ADULT;
                    break;
                case 2:
                    ticketType = TicketType.CHILD;
                    break;
                case 3:
                    ticketType = TicketType.STUDENT;
                    break;
                case 4:
                    ticketType = TicketType.SENIOR;
                    break;
                default:
                    ticketType = TicketType.ADULT;
            }
            ticketTypes.add(ticketType);
        }

        // 计算总价并确认
        double totalPrice = 0;
        for (int i = 0; i < selectedSeats.size(); i++) {
            TicketType ticketType = ticketTypes.get(i);
            double price = schedule.getPrice() * ticketType.getDiscountRate();
            
            // 早场优惠
            if (schedule.getShowTime().getHour() == 10) {
                price *= 0.9;
            }
            
            totalPrice += price;
        }

        System.out.println("\n购票信息确认：");
        Optional<Movie> movieOpt = movieService.findMovieById(schedule.getMovieId());
        String movieTitle = movieOpt.map(Movie::getTitle).orElse("未知影片");
        
        System.out.println("影片：" + movieTitle);
        System.out.println("放映厅：" + schedule.getHallId());
        System.out.println("放映时间：" + schedule.getShowTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        
        for (int i = 0; i < selectedSeats.size(); i++) {
            int[] seat = selectedSeats.get(i);
            TicketType ticketType = ticketTypes.get(i);
            System.out.printf("座位：%d排%d座 (%s)\n", seat[0] + 1, seat[1] + 1, ticketType.getDescription());
        }
        
        System.out.printf("总价：%.2f 元\n", totalPrice);

        boolean confirm = InputUtil.readConfirmation("确认购票？");
        
        if (confirm) {
            List<Ticket> tickets = ticketService.sellTickets(scheduleId, selectedSeats, ticketTypes);
            if (tickets != null && !tickets.isEmpty()) {
                System.out.println("\n售票成功！");
                System.out.println("电影票信息：");
                for (Ticket ticket : tickets) {
                    System.out.println("========================================");
                    System.out.println("电子票号：" + ticket.getTicketId());
                    System.out.println("影片：" + ticket.getMovieTitle());
                    System.out.println("放映厅：" + ticket.getCinemaHall());
                    System.out.println("放映时间：" + ticket.getShowTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
                    System.out.println("座位：" + (ticket.getSeatRow() + 1) + "排" + (ticket.getSeatCol() + 1) + "座");
                    System.out.println("票类型：" + ticket.getTicketType().getDescription());
                    System.out.println("票价：" + String.format("%.2f", ticket.getPrice()) + " 元");
                    System.out.println("购票时间：" + ticket.getPurchaseTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                }
                System.out.printf("\n应收金额：%.2f 元\n", totalPrice);
            } else {
                System.out.println("售票失败！可能是座位冲突。");
            }
        } else {
            System.out.println("操作已取消。");
        }
        InputUtil.pauseForUser();
    }

    /**
     * 退票
     */
    private void refundTicket() {
        System.out.println("\n==================== 退票 ====================");
        
        String ticketId = InputUtil.readNonEmptyString("请输入电子票号: ");
        Optional<Ticket> ticketOpt = ticketService.findTicketById(ticketId);
        
        if (!ticketOpt.isPresent()) {
            System.out.println("票务信息不存在！");
            InputUtil.pauseForUser();
            return;
        }

        Ticket ticket = ticketOpt.get();
        
        if (ticket.isRefunded()) {
            System.out.println("该票已经退过了！");
            InputUtil.pauseForUser();
            return;
        }

        System.out.println("票务信息：");
        displayTicketInfo(ticket);

        if (!ticket.canRefund()) {
            System.out.println("该票不满足退票条件（开演前1小时内不允许退票）！");
            InputUtil.pauseForUser();
            return;
        }

        double refundAmount = ticket.calculateRefundAmount();
        System.out.printf("退票金额：%.2f 元\n", refundAmount);

        boolean confirm = InputUtil.readConfirmation("确认退票？");
        
        if (confirm) {
            if (ticketService.refundTicket(ticketId)) {
                System.out.println("退票成功！");
                System.out.printf("退还金额：%.2f 元\n", refundAmount);
            } else {
                System.out.println("退票失败！");
            }
        } else {
            System.out.println("操作已取消。");
        }
        InputUtil.pauseForUser();
    }

    /**
     * 查询票务信息
     */
    private void queryTicket() {
        System.out.println("\n==================== 查询票务 ====================");
        
        String ticketId = InputUtil.readNonEmptyString("请输入电子票号: ");
        Optional<Ticket> ticketOpt = ticketService.findTicketById(ticketId);
        
        if (ticketOpt.isPresent()) {
            displayTicketInfo(ticketOpt.get());
        } else {
            System.out.println("票务信息不存在！");
        }
        InputUtil.pauseForUser();
    }

    /**
     * 显示票务信息
     */
    private void displayTicketInfo(Ticket ticket) {
        System.out.println("\n票务详细信息：");
        System.out.println("电子票号：" + ticket.getTicketId());
        System.out.println("影片：" + ticket.getMovieTitle());
        System.out.println("放映厅：" + ticket.getCinemaHall());
        System.out.println("放映时间：" + ticket.getShowTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        System.out.println("座位：" + (ticket.getSeatRow() + 1) + "排" + (ticket.getSeatCol() + 1) + "座");
        System.out.println("票类型：" + ticket.getTicketType().getDescription());
        System.out.println("票价：" + String.format("%.2f", ticket.getPrice()) + " 元");
        System.out.println("购票时间：" + ticket.getPurchaseTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        System.out.println("状态：" + (ticket.isRefunded() ? "已退票" : "有效"));
        
        if (!ticket.isRefunded() && ticket.canRefund()) {
            System.out.println("可退票金额：" + String.format("%.2f", ticket.calculateRefundAmount()) + " 元");
        }
    }

    /**
     * 显示个人信息
     */
    private void displayUserInfo(User user) {
        System.out.println("\n==================== 个人信息 ====================");
        System.out.println("用户ID：" + user.getUserId());
        System.out.println("用户名：" + user.getUsername());
        System.out.println("用户类型：" + user.getUserType().getDescription());
        System.out.println("手机号：" + user.getPhoneNumber());
        System.out.println("注册时间：" + user.getRegistrationTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        InputUtil.pauseForUser();
    }

    /**
     * 截断字符串
     */
    private String truncateString(String str, int maxLength) {
        if (str == null) return "";
        return str.length() > maxLength ? str.substring(0, maxLength - 3) + "..." : str;
    }
    
    /**
     * 格式化中文字符串，考虑中文字符的显示宽度
     */
    private String formatChineseString(String str, int maxDisplayWidth) {
        if (str == null) return "";
        
        int displayWidth = 0;
        StringBuilder result = new StringBuilder();
        
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            int charWidth = isChinese(c) ? 2 : 1; // 中文字符占2个位置，英文字符占1个位置
            
            if (displayWidth + charWidth > maxDisplayWidth) {
                if (maxDisplayWidth >= 3) {
                    // 如果还有空间，添加省略号
                    if (displayWidth <= maxDisplayWidth - 3) {
                        result.append("...");
                    } else {
                        // 替换最后几个字符为省略号
                        while (result.length() > 0 && displayWidth > maxDisplayWidth - 3) {
                            char lastChar = result.charAt(result.length() - 1);
                            result.deleteCharAt(result.length() - 1);
                            displayWidth -= isChinese(lastChar) ? 2 : 1;
                        }
                        result.append("...");
                    }
                }
                break;
            }
            
            result.append(c);
            displayWidth += charWidth;
        }
        
        // 添加空格填充到指定宽度
        while (displayWidth < maxDisplayWidth) {
            result.append(" ");
            displayWidth++;
        }
        
        return result.toString();
    }
    
    /**
     * 判断字符是否为中文字符
     */
    private boolean isChinese(char c) {
        return c >= 0x4E00 && c <= 0x9FFF;
    }
}